package com.benzhu.shiro.Filter;

import com.benzhu.shiro.realm.CustomRealm;
import com.benzhu.shiro.session.CustomSessionManager;
import com.benzhu.shiro.session.RedisSessionDao;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {

    @Resource(name = "realm")
    private CustomRealm customRealm;
    @Resource(name = "redisSessionDao")
    private RedisSessionDao redisSessionDao;

    @Bean(name="shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        //配置登录的url和登录成功的url以及验证失败的url
        bean.setLoginUrl("/login");
        bean.setUnauthorizedUrl("/error");

        //配置自定义的Filter
        Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
        filtersMap.put("roleOrFilter", new RolesOrFilter());
        bean.setFilters(filtersMap);
        //配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/sublogin", "anon");
        filterChainDefinitionMap.put("/usererror", "anon");
        filterChainDefinitionMap.put("/roles1", "roles[admin]");
        filterChainDefinitionMap.put("/roles2", "roles[admin,user]");
        filterChainDefinitionMap.put("/permission1", "perms[user:update]");
        filterChainDefinitionMap.put("/permission2", "perms[user:update,user:select]");
        filterChainDefinitionMap.put("/roles3", "roleOrFilter[admin,user]");
        filterChainDefinitionMap.put("/**","authc");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }



    //配置核心安全事务管理器
    @Bean(name="securityManager")
    public DefaultWebSecurityManager securityManager(@Qualifier("sessionManager")DefaultWebSessionManager sessionManager) {
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
        //配置自定义Realm
        manager.setRealm(customRealm);
        //配置自定义sessionManager
        manager.setSessionManager(sessionManager);
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //创建加密对象
        matcher.setHashAlgorithmName("md5"); //加密的算法
        matcher.setHashIterations(1);//加密次数
        customRealm.setCredentialsMatcher(matcher); //放入自定义Realm
        return manager;
    }

    //以下是开启注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    //配置session
    @Bean(name="sessionManager")
    public CustomSessionManager sessionManager(){
        //把sessionManager注入Bean
        CustomSessionManager manager = new CustomSessionManager();
        manager.setSessionDAO(redisSessionDao);
        return manager;
    }
}
